package cn.changeforyou.web.dao.mybatis.ext.service;

import cn.changeforyou.base.exception.ExceptionFactory;
import cn.changeforyou.web.dao.mybatis.ext.dao.BaseDao;
import cn.changeforyou.web.dao.mybatis.ext.exception.DaoExceptionEnum;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * 因为体验良好的分页api要么用service 代理, 要么写mybatis的代理, 所以service来了
 * 形如
 * <code>
 *     Page<T> listPage(condition, pageable);
 * </code>
 * @author zhyu
 * @version 1.0
 * @date 2022/2/16 17:51
 */
public interface BaseService<Entity, Mapper extends BaseDao<Entity>> {

    Mapper getBaseDao();

    /**
     * 获取全部Map
     * @return
     */
    default List<Map<String, Object>> getAllMap(){
        Entity entity = instanceEntity();
        return getBaseDao().selectMapsByEntity(entity);
    }

    /**
     * 获取全部实体列表
     * @return
     */
    default List<Entity> getAllEntities() {
        Entity entity = instanceEntity();
        return getBaseDao().selectListByEntity(entity);
    }

    /**
     * 实例化实体
     * @return
     */
    default Entity instanceEntity() {
        Type superclass = getClass().getGenericSuperclass();
        ParameterizedType parameterizedType = null;
        Entity entity = null;
        Class clazz = null;
        if (superclass instanceof ParameterizedType) {
            parameterizedType = (ParameterizedType) superclass;
            Type[] typeArray = parameterizedType.getActualTypeArguments();
            if (typeArray != null && typeArray.length > 0) {
                clazz = (Class<Entity>) typeArray[0];
                try {
                    entity = (Entity) clazz.newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return entity;
    }

    default Page<Entity> pageByCondition(Object condition, Pageable pageable) {
        if(pageable.getPageSize() > 0 && pageable.getPageNumber() > 0) {
            PageRequest pageInfo = PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize());
            Mapper baseDao = getBaseDao();
            PageInfo<Entity> localPage =
                    PageHelper.startPage(pageable.getPageNumber(), pageable.getPageSize()).doSelectPageInfo(() -> baseDao.selectListByCondition(condition));
            Page<Entity> page = new PageImpl(localPage.getList(), pageInfo,
                    localPage.getTotal());
            return page;
        }else {
            throw ExceptionFactory.jsonException(DaoExceptionEnum.PAGE_PARAM_ERROR);
        }

    }
}
